package reserve

import (
    "time"
	"strconv"
	"encoding/json"
	"dhfshop/controllers/base"
	"dhfshop/domain/reserves"
	"dhfshop/models/reserve"
	"dhfshop/models/member"
	"dhfshop/models/isv"
	"dhfshop/domain/im"
	"dhfshop/models/consts"
	"github.com/astaxie/beego"
	"dhfshop/domain/nsqproc"
	"github.com/astaxie/beego/validation"
)

type ReservationController struct {
	base.BaseController
}

func (this *ReservationController) List() {
	query,_, fields, order_by, offset, limit, err := this.GetQueryPara()
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	curRoleId := this.Ctx.Input.GetData("curRoleId").(int) 
	companyId := int64(this.Ctx.Input.GetData("curCompanyId").(int))
	curUserId := int64(this.Ctx.Input.GetData("curUserId").(int))
	//beego.Debug("curRoleId:",curRoleId)
	//beego.Debug("companyId:", companyId)
	//beego.Debug("curUserId", curUserId)
	if curRoleId == 1 {
		query["member_id"] = strconv.FormatInt(curUserId, 10)
		query["partner_id"] = strconv.FormatInt(companyId, 10)
	}else if curRoleId == 2 {
	    query["partner_id"] = strconv.FormatInt(companyId, 10)
	}else{
	
	}
	l, cnt, err := reserve.GetAllReservations(query, fields, order_by, offset, limit)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	r := struct {
		TotalCount   int64                 `json:"total_count"`
		Reservation []*reserve.Reservation `json:"reservations"`
	}{TotalCount: cnt, Reservation: l}
	this.Data["json"] = r
	this.ServeJSON()
}

// 只能买家角色预约，后台预约的话，需要重写一个接口
func (this *ReservationController) Post() {
	var v reserve.Reservation
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Required(v.SchemaId, "schema_id")
	valid.Required(v.PeriodId, "period_id")
	valid.Required(v.TimeslotId, "timeslot_id")
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key + " " + valid.Errors[0].Message)
		return
	}
	v.PartnerId = int64(this.Ctx.Input.GetData("curCompanyId").(int))
	curUserId := int64(this.Ctx.Input.GetData("curUserId").(int))
	/*
	curRoleId := this.Ctx.Input.GetData("curRoleId").(int) 
	if curRoleId == 1 {
		curAppId := this.Ctx.Input.GetData("curAppId").(string)		
	} else {
	    
	}
	*/
	v.MemberId = int64(curUserId)
	if ok := reserve.ExistReservation(v.SchemaId,v.PeriodId,v.MemberId); ok {
	    this.ServeError("同一个项目同一个用户同一天只能预约一次")
		return 
	}
	schema, err := reserve.GetSchemaById(v.SchemaId)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	v.StoreId = schema.StoreId
	v.Schema = schema
	period, err := reserve.GetPeriodById(v.PeriodId)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	v.Period = period
	timeslot, err := reserve.GetTimeslotById(v.TimeslotId)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	curNo, err := reservelayer.ReduceSource(timeslot)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	v.SourceAt = period.SourceAt
	v.Start = timeslot.Start 
	v.End = timeslot.End
	v.OrderSeq = curNo
	v.Timeslot = timeslot
	beego.Debug("OrderSeq:", v.OrderSeq)
	id, err := reserve.AddReservation(&v)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	v.ReservationId = int64(id)
	members, err := member.GetMemberById(v.MemberId)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	if custAccount, err := isv.GetCustAccountByAppId(members.AppId); err == nil {
		if templateId, err := imlayer.GetTemplateId(v.PartnerId,members.AppId,"AT0104"); err == nil {
		    page := ""
			sourceAtStr := v.Period.SourceAt.Format(consts.DATE_FORMAT)
		    err = imlayer.ReserveSuccessTempMsg(custAccount.AccessToken,page,members.OpenID,templateId,v.FormId,schema.Name,sourceAtStr)
			if err != nil {
				beego.Debug("ReserveSuccessTempMsg:", err.Error())
			}
		}
	}
	types := "ReminderArrived"
	ttlSeconds := v.SourceAt.Unix() - time.Now().UTC().Unix() + 24*3600
	body := struct {
		ReservationId int64 `json:"reservation_id"`
	}{ReservationId: v.ReservationId}
	if callBackData, err := json.Marshal(&body); err == nil {
		if err = nsqproc.RpcAddTimerTask(types, string(callBackData), int(ttlSeconds)); err != nil {
		    beego.Debug("RpcAddTimerTask:", err.Error())
		}
	}
	rsp := struct {
		ReservationId  int64     `json:"reservation_id"`
		Modified        time.Time `json:"modified"`
	}{ReservationId: id, Modified: time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}

func (this *ReservationController) Update() {
	var v reserve.Reservation
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Required(v.ReservationId, "reservation_id")
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key + " " + valid.Errors[0].Message)
		return
	}
	if v.SchemaId > 0 {
	    schema, err := reserve.GetSchemaById(v.SchemaId)
		if err != nil {
			this.ServeError(err.Error())
			return 
		}
		v.Schema = schema
	}
	updateFields, err := this.GetUpdateFields(v, "", "form", []string{"reservation_id"})
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	if v.PeriodId > 0 {
	    period, err := reserve.GetPeriodById(v.PeriodId)
		if err != nil {
			this.ServeError(err.Error())
			return 
		}
		v.Period = period
		v.SourceAt = period.SourceAt
		updateFields = append(updateFields, "source_at")
	}
	if v.TimeslotId > 0 {
	    timeslot, err := reserve.GetTimeslotById(v.TimeslotId)
		if err != nil {
			this.ServeError(err.Error())
			return 
		}
		v.Timeslot = timeslot
		v.Start = timeslot.Start 
	    v.End = timeslot.End
		updateFields = append(updateFields, "start", "end")
	}
	
	if len(updateFields) > 0 {
		err := reserve.UpdateReservationById(&v, updateFields...)
		if err != nil {
			this.ServeError(err.Error())
			return
		}
	}
	rsp := struct {
		ReservationId  int64     `json:"reservation_id"`
		Modified       time.Time `json:"modified"`
	}{ReservationId: v.ReservationId, Modified: time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}

func (this *ReservationController) Delete() {
	var v reserve.Reservation
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Required(v.ReservationId, "reservation_id")
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key + " " + valid.Errors[0].Message)
		return
	}
	err := reserve.DeleteReservation(v.ReservationId)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	r := struct {
		ReservationId  int64       `json:"reservation_id"`
		Modified       time.Time   `json:"modified"`
	}{ReservationId: v.ReservationId, Modified: time.Now().UTC()}
	this.Data["json"] = r
	this.ServeJSON()
}

